package jrain.fw.script.expression;

import java.util.List;
import java.util.Map;

import jrain.fw.script.operator.UnaryOperator;
import jrain.fw.script.resolver.VariableResolver;
import jrain.fw.script.tools.ELException;
import jrain.fw.script.tools.Logger;

public class UnaryOperatorExpression extends Expression {
	 
	UnaryOperator mOperator;

	public UnaryOperator getOperator() {
		return mOperator;
	}

	public void setOperator(UnaryOperator pOperator) {
		mOperator = pOperator;
	}

	// -------------------------------------
	// property operators

	List<?> mOperators;

	public List<?> getOperators() {
		return mOperators;
	}

	public void setOperators(List<?> pOperators) {
		mOperators = pOperators;
	}

	// -------------------------------------
	// property expression

	Expression mExpression;

	public Expression getExpression() {
		return mExpression;
	}

	public void setExpression(Expression pExpression) {
		mExpression = pExpression;
	}

	// -------------------------------------

	/**
	 * Constructor
	 */
	public UnaryOperatorExpression(UnaryOperator pOperator, List<?> pOperators, Expression pExpression) {
		mOperator = pOperator;
		mOperators = pOperators;
		mExpression = pExpression;
	}

	// -------------------------------------
	// Expression methods
	// -------------------------------------

	/**
	 * Returns the expression in the expression language syntax
	 */
	public String getExpressionString() {
		StringBuffer buf = new StringBuffer();
		buf.append("(");
		if (mOperator != null) {
			buf.append(mOperator.getOperatorSymbol());
			buf.append(" ");
		} else {
			for (int i = 0; i < mOperators.size(); i++) {
				UnaryOperator operator = (UnaryOperator) mOperators.get(i);
				buf.append(operator.getOperatorSymbol());
				buf.append(" ");
			}
		}
		buf.append(mExpression.getExpressionString());
		buf.append(")");
		return buf.toString();
	}

	// -------------------------------------

	/**
	 * Evaluates to the literal value
	 */
	public Object evaluate(Object pContext, VariableResolver pResolver, Map<Object, Object> functions, String defaultPrefix, Logger pLogger)
			throws ELException {
		Object value = mExpression.evaluate(pContext, pResolver, functions, defaultPrefix, pLogger);
		if (mOperator != null) {
			value = mOperator.apply(value, pContext, pLogger);
		} else {
			for (int i = mOperators.size() - 1; i >= 0; i--) {
				UnaryOperator operator = (UnaryOperator) mOperators.get(i);
				value = operator.apply(value, pContext, pLogger);
			}
		}
		return value;
	}

	// -------------------------------------
}
